' Interrupts in assembly language
'  Turn LED on.  Interrupt on PORTB.0 (INTE) turns LED off.
'  Program waits .5 seconds and turns LED back on.

led     var     PORTB.7

wsave   var     byte $20 system
'wsave1  var     byte $a0 system ' Necessary for devices with RAM in bank1
'wsave2  var     byte $120 system ' Necessary for devices with RAM in bank2
'wsave3  var     byte $1a0 system ' Necessary for devices with RAM in bank3
ssave   var     byte bank0 system
psave   var     byte bank0 system


        Goto start              ' Skip around interrupt handler

' Define interrupt handler
define  INTHAND myint

' Assembly language interrupt handler
asm

; Save W, STATUS and PCLATH registers, if not done previously
myint   movwf   wsave
        swapf   STATUS, W
        clrf    STATUS
        movwf   ssave
        movf    PCLATH, W
        movwf   psave

; Insert interrupt code here
; Save and restore FSR and any other registers used

        bcf     _led            ; If interrupt, turn off LED
        bcf     INTCON, 1       ; Clear interrupt flag

; Restore saved registers
        movf    psave, W
        movwf   PCLATH
        swapf   ssave, W
        movwf   STATUS
        swapf   wsave, F
        swapf   wsave, W

        retfie                  ; Return from interrupt

endasm


start:  TRISB = $7f             ' LED out, rest in
        OPTION_REG = $7f        ' Enable PORTB pullups

        INTCON = $90            ' Enable INTE interrupt

        led = 1                 ' Turn LED on

loop:   If led = 1 Then loop    ' Wait here while LED is still on
                                ' If we get here, LED is off
        Pause   500             ' Wait .5 seconds
        Goto    start           ' Start over (turn LED back on)
